﻿using System;
using System.ServiceProcess;

namespace DebuggableInstallableService
{
    public partial class WindowsServiceHarness : ServiceBase
    {
        private IWindowsService _implementer;

        internal WindowsServiceHarness()
        {
            InitializeComponent();
        }

        public WindowsServiceHarness(IWindowsService implementation)
            : this()
        {
            if(implementation == null)
            {
                throw new ArgumentNullException(@"implementation", "IWindowService cannot be null in call to GenericWindowsService");
            }

            _implementer = implementation;

            ConfigureServiceFromAttributes(implementation);
        }

        protected override void OnStart(string[] args)
        {
            _implementer.OnStart(args);
        }

        protected override void OnStop()
        {
            _implementer.OnStop();
        }

        protected override void OnPause()
        {
            _implementer.OnPause();
        }

        protected override void OnContinue()
        {
            _implementer.OnContinue();
        }

        protected override void OnShutdown()
        {
            _implementer.OnShutdown();
        }

        protected override void OnCustomCommand(int command)
        {
            _implementer.OnCustomCommand(command);
        }

        private void ConfigureServiceFromAttributes(IWindowsService serviceImplementation)
        {
            var attr = serviceImplementation.GetType().GetAttribute<WindowsServiceAttribute>();

            if(attr != null)
            {
                EventLog.Source = string.IsNullOrEmpty(attr.EventLogSource)
                                      ? "WindowsServiceHarness"
                                      : attr.EventLogSource;

                CanStop = attr.CanStop;
                CanPauseAndContinue = attr.CanPauseAndContinue;
                CanShutdown = attr.CanShutdown;

                CanHandlePowerEvent = false;

                CanHandleSessionChangeEvent = false;

                AutoLog = true;
            }
            else
            {
                throw new InvalidOperationException(string.Format("IWindowsService implementor {0} must have a WIndowsServiceAttribute.", 
                    serviceImplementation.GetType().FullName));
            }
        }
    }
}
